﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Specialized;
using Microsoft.SharePoint.WebControls;
using System.Data;
using System.DirectoryServices;
using System.Web;
using System.Text;

namespace Presentation.ABDI.WebPart.VWPAlterarSenha
{
    public partial class VWPAlterarSenhaUserControl : UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            lblMensagemErro.Text = SPContext.Current.Web.CurrentUser.LoginName.Split('\\')[1];
            lblMensagemErro.Visible = true;
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
        }

        # region Button Controls
        protected void btnAlteraSenha_Click(object sender, EventArgs e)
        {
            ChangePass();
        }

        protected void btnCancelarSenha_Click(object sender, EventArgs e)
        {
            Response.Redirect("http://sapidev.abdi.com.br/pwa");
        }
        #endregion

        # region Métodos
        //Método que Altera a Senha do Usuário
        private void ChangePass()
        {
            var currentUserName = SPContext.Current.Web.CurrentUser.LoginName.Split('\\')[1];
            String senhaAtual = txtSenhaAtual.Text;
            String novaSenha = txtNovaSenha.Text;
            String confirmarSenha = txtConfirmarSenha.Text;

            if (novaSenha == null || !novaSenha.Equals(confirmarSenha))
            {
                lblMensagemErro.Text = "Informe os dados corretamente!";
                lblMensagemErro.Visible = true;
                return;
            }

            if (novaSenha.Length < 8)
            {
                lblMensagemErro.Text = "A senha precisa ter no mínimo 8 caracteres.";
                lblMensagemErro.Visible = true;
                return;
            }

            if (!Authenticate(currentUserName, senhaAtual))
            {
                lblMensagemErro.Text = "Senha Incorreta.";
                lblMensagemErro.Visible = true;
                return;
            }

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                DirectoryEntry dirEntry = new DirectoryEntry("LDAP://192.168.1.21", "svcsharepointdev", "AB562c8a");
                DirectorySearcher userSearcher = new DirectorySearcher(dirEntry);
                userSearcher.Filter = "(sAMAccountName=" + EscapeLdapSearchFilter(currentUserName) + ")";
                var foundedUser = userSearcher.FindOne();
                if (foundedUser != null)
                {
                    try
                    {
                        var userEntry = foundedUser.GetDirectoryEntry();
                        ResetPassword(userEntry, novaSenha);
                        lblMensagemErro.Text = "Sua senha foi alterada com sucesso! Esta sessão será finalizada.";
                        lblMensagemErro.Visible = true;
                        Response.Write("<script> alert ('Sua senha foi alterada com sucesso! Esta sessão será finalizada.');document.location = '../_layouts/signout.aspx/'</script>");
                    }
                    catch (Exception)
                    {
                        lblMensagemErro.Text = "Dados Incorretos. Tente novamente!";
                        lblMensagemErro.Visible = true;
                    }
                }
                else
                {
                    lblMensagemErro.Text = String.Format("Usuário {0} inexistente!", currentUserName);
                    lblMensagemErro.Visible = true;
                }
            });
        }

        private bool Authenticate(string userName, string password)
        {
            bool authentic = false;
            try
            {
                DirectoryEntry entry = new DirectoryEntry("LDAP://192.168.0.215", userName, password);
                object nativeObject = entry.NativeObject;
                authentic = true;
            }
            catch (DirectoryServicesCOMException) { }
            return authentic;
        }

        public void ResetPassword(DirectoryEntry uEntry, string password)
        {
            uEntry.Invoke("SetPassword", new object[] { password });
            uEntry.Properties["LockOutTime"].Value = 0; //unlock account
            uEntry.CommitChanges();
            uEntry.RefreshCache();
            uEntry.Close();
        }

        /// <summary>
        /// Escapes the LDAP search filter to prevent LDAP injection attacks.
        /// </summary>
        /// <param name="searchFilter">The search filter.</param>
        /// <see cref="https://blogs.oracle.com/shankar/entry/what_is_ldap_injection" />
        /// <see cref="http://msdn.microsoft.com/en-us/library/aa746475.aspx" />
        /// <returns>The escaped search filter.</returns>
        private static string EscapeLdapSearchFilter(string searchFilter)
        {
            StringBuilder escape = new StringBuilder();
            for (int i = 0; i < searchFilter.Length; ++i)
            {
                char current = searchFilter[i];
                switch (current)
                {
                    case '\\':
                        escape.Append(@"\5c");
                        break;
                    case '*':
                        escape.Append(@"\2a");
                        break;
                    case '(':
                        escape.Append(@"\28");
                        break;
                    case ')':
                        escape.Append(@"\29");
                        break;
                    case '\u0000':
                        escape.Append(@"\00");
                        break;
                    case '/':
                        escape.Append(@"\2f");
                        break;
                    default:
                        escape.Append(current);
                        break;
                }
            }

            return escape.ToString();
        }
        #endregion
    }
}
